{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "f2b7c9d0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " 词汇表： ['Xiaoxue', 'Kage', 'Boss', 'Xiaobing', 'is', 'Niuzong', 'Teacher', 'Mazong', 'Student']\n",
      " 词汇到索引的字典： {'Xiaoxue': 0, 'Kage': 1, 'Boss': 2, 'Xiaobing': 3, 'is': 4, 'Niuzong': 5, 'Teacher': 6, 'Mazong': 7, 'Student': 8}\n",
      " 索引到词汇的字典： {0: 'Xiaoxue', 1: 'Kage', 2: 'Boss', 3: 'Xiaobing', 4: 'is', 5: 'Niuzong', 6: 'Teacher', 7: 'Mazong', 8: 'Student'}\n",
      " 词汇表大小： 9\n"
     ]
    }
   ],
   "source": [
    "# 定义一个句子列表，后面会用这些句子来训练 CBOW 和 Skip-Gram 模型\n",
    "sentences = [\"Kage is Teacher\", \"Mazong is Boss\", \"Niuzong is Boss\",\n",
    "             \"Xiaobing is Student\", \"Xiaoxue is Student\",]\n",
    "# 将所有句子连接在一起，然后用空格分隔成多个单词\n",
    "words = ' '.join(sentences).split()\n",
    "# 构建词汇表，去除重复的词\n",
    "word_list = list(set(words))\n",
    "# 创建一个字典，将每个词映射到一个唯一的索引\n",
    "word_to_idx = {word: idx for idx, word in enumerate(word_list)}\n",
    "# 创建一个字典，将每个索引映射到对应的词\n",
    "idx_to_word = {idx: word for idx, word in enumerate(word_list)}\n",
    "voc_size = len(word_list) # 计算词汇表的大小\n",
    "print(\" 词汇表：\", word_list) # 输出词汇表\n",
    "print(\" 词汇到索引的字典：\", word_to_idx) # 输出词汇到索引的字典\n",
    "print(\" 索引到词汇的字典：\", idx_to_word) # 输出索引到词汇的字典\n",
    "print(\" 词汇表大小：\", voc_size) # 输出词汇表大小"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "7255a046",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Skip-Gram 数据样例（未编码）： [('is', 'Kage'), ('Teacher', 'Kage'), ('Kage', 'is')]\n"
     ]
    }
   ],
   "source": [
    "# 生成 Skip-Gram 训练数据\n",
    "def create_skipgram_dataset(sentences, window_size=2):\n",
    "    data = [] # 初始化数据\n",
    "    for sentence in sentences: # 遍历句子\n",
    "        sentence = sentence.split()  # 将句子分割成单词列表\n",
    "        for idx, word in enumerate(sentence):  # 遍历单词及其索引\n",
    "            # 获取相邻的单词，将当前单词前后各 N 个单词作为相邻单词\n",
    "            for neighbor in sentence[max(idx - window_size, 0): \n",
    "                        min(idx + window_size + 1, len(sentence))]:\n",
    "                if neighbor != word:  # 排除当前单词本身\n",
    "                    # 将相邻单词与当前单词作为一组训练数据\n",
    "                    data.append((neighbor, word))\n",
    "    return data\n",
    "# 使用函数创建 Skip-Gram 训练数据\n",
    "skipgram_data = create_skipgram_dataset(sentences)\n",
    "# 打印未编码的 Skip-Gram 数据样例（前 3 个）\n",
    "print(\"Skip-Gram 数据样例（未编码）：\", skipgram_data[:3])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "cd08ed75",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "One-Hot 编码前的单词： Teacher\n",
      "One-Hot 编码后的向量： tensor([0., 0., 0., 0., 0., 0., 1., 0., 0.])\n",
      "Skip-Gram 数据样例（已编码）： [(tensor([0., 0., 0., 0., 1., 0., 0., 0., 0.]), 1), (tensor([0., 0., 0., 0., 0., 0., 1., 0., 0.]), 1), (tensor([0., 1., 0., 0., 0., 0., 0., 0., 0.]), 4)]\n"
     ]
    }
   ],
   "source": [
    "# 定义 One-Hot 编码函数\n",
    "import torch # 导入 torch 库\n",
    "def one_hot_encoding(word, word_to_idx):    \n",
    "    tensor = torch.zeros(len(word_to_idx)) # 创建一个长度与词汇表相同的全 0 张量  \n",
    "    tensor[word_to_idx[word]] = 1  # 将对应词的索引设为 1\n",
    "    return tensor  # 返回生成的 One-Hot 向量\n",
    "# 展示 One-Hot 编码前后的数据\n",
    "word_example = \"Teacher\"\n",
    "print(\"One-Hot 编码前的单词：\", word_example)\n",
    "print(\"One-Hot 编码后的向量：\", one_hot_encoding(word_example, word_to_idx))\n",
    "# 展示编码后的 Skip-Gram 训练数据样例\n",
    "print(\"Skip-Gram 数据样例（已编码）：\", [(one_hot_encoding(context, word_to_idx), \n",
    "          word_to_idx[target]) for context, target in skipgram_data[:3]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "e6c40903",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Skip-Gram 模型： SkipGram(\n",
      "  (input_to_hidden): Embedding(9, 2)\n",
      "  (hidden_to_output): Linear(in_features=2, out_features=9, bias=False)\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "# 定义 Skip-Gram 模型\n",
    "import torch.nn as nn # 导入 neural network\n",
    "class SkipGram(nn.Module):\n",
    " def __init__(self, voc_size, embedding_size):\n",
    "    super(SkipGram, self).__init__()\n",
    "    # 从词汇表大小到嵌入大小的嵌入层（权重矩阵）\n",
    "    self.input_to_hidden = nn.Embedding(voc_size, embedding_size)  \n",
    "    # 从嵌入大小到词汇表大小的线性层（权重矩阵）\n",
    "    self.hidden_to_output = nn.Linear(embedding_size, voc_size, bias=False) \n",
    " def forward(self, X):\n",
    "    hidden_layer = self.input_to_hidden(X)  # 生成隐藏层：[batch_size, embedding_size]\n",
    "    output_layer = self.hidden_to_output(hidden_layer)  # 生成输出层：[batch_size, voc_size]\n",
    "    return output_layer  \n",
    "embedding_size = 2 # 设定嵌入层的大小，这里选择 2 是为了方便展示\n",
    "skipgram_model = SkipGram(voc_size, embedding_size)  # 实例化 Skip-Gram 模型\n",
    "print(\"Skip-Gram 模型：\", skipgram_model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "010e5aa3",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch: 100, Loss: 2.123114252090454\n",
      "Epoch: 200, Loss: 2.0455686529477437\n",
      "Epoch: 300, Loss: 2.008841876188914\n",
      "Epoch: 400, Loss: 1.9867347657680512\n",
      "Epoch: 500, Loss: 1.9700093587239584\n",
      "Epoch: 600, Loss: 1.9554399251937866\n",
      "Epoch: 700, Loss: 1.9419651488463083\n",
      "Epoch: 800, Loss: 1.929264227549235\n",
      "Epoch: 900, Loss: 1.9172542591889699\n",
      "Epoch: 1000, Loss: 1.9059183279673257\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 训练 Skip-Gram 类\n",
    "learning_rate = 0.001 # 设置学习速率\n",
    "epochs = 1000 # 设置训练轮次\n",
    "criterion = nn.CrossEntropyLoss()  # 定义交叉熵损失函数\n",
    "import torch.optim as optim # 导入随机梯度下降优化器\n",
    "optimizer = optim.SGD(skipgram_model.parameters(), lr=learning_rate)  \n",
    "# 开始训练循环\n",
    "loss_values = []  # 用于存储每轮的平均损失值\n",
    "for epoch in range(epochs):\n",
    "    loss_sum = 0 # 初始化损失值\n",
    "    for context, target in skipgram_data:        \n",
    "        X = torch.tensor([word_to_idx[target]], dtype=torch.long)  # # 输入是中心词\n",
    "        y_true = torch.tensor([word_to_idx[context]], dtype=torch.long)  # 目标词是周围词\n",
    "        y_pred = skipgram_model(X)  # 计算预测值\n",
    "        loss = criterion(y_pred, y_true)  # 计算损失\n",
    "        loss_sum += loss.item() # 累积损失\n",
    "        optimizer.zero_grad()  # 清空梯度\n",
    "        loss.backward()  # 反向传播\n",
    "        optimizer.step()  # 更新参数\n",
    "    if (epoch+1) % 100 == 0: # 输出每 100 轮的损失，并记录损失\n",
    "      print(f\"Epoch: {epoch+1}, Loss: {loss_sum/len(skipgram_data)}\")  \n",
    "      loss_values.append(loss_sum / len(skipgram_data))\n",
    "# 绘制训练损失曲线\n",
    "import matplotlib.pyplot as plt # 导入 matplotlib\n",
    "# 绘制二维词向量图\n",
    "plt.rcParams[\"font.family\"]=['SimHei'] # 用来设定字体样式\n",
    "plt.rcParams['font.sans-serif']=['SimHei'] # 用来设定无衬线字体样式\n",
    "plt.rcParams['axes.unicode_minus']=False # 用来正常显示负号\n",
    "plt.plot(range(1, epochs//100 + 1), loss_values) # 绘图\n",
    "plt.title(' 训练损失曲线 ') # 图题\n",
    "plt.xlabel(' 轮次 ') # X 轴 Label\n",
    "plt.ylabel(' 损失 ') # Y 轴 Label\n",
    "plt.show() # 显示图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "91da6631",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Skip-Gram 词嵌入：\n",
      "Xiaoxue: [-1.185277  1.298675]\n",
      "Kage: [ 0.6576963 -0.7966969]\n",
      "Boss: [-0.45424542 -2.8292804 ]\n",
      "Xiaobing: [0.15641613 0.47727743]\n",
      "is: [-0.06019835  0.9512902 ]\n",
      "Niuzong: [0.12958734 0.22813088]\n",
      "Teacher: [-0.9217507 -1.2967763]\n",
      "Mazong: [-0.41714072  0.65298873]\n",
      "Student: [ 1.1987574 -1.3199298]\n"
     ]
    }
   ],
   "source": [
    "# 输出 Skip-Gram 习得的词嵌入\n",
    "print(\"Skip-Gram 词嵌入：\")\n",
    "for word, idx in word_to_idx.items(): # 输出每个词的嵌入向量\n",
    " print(f\"{word}: {skipgram_model.input_to_hidden.weight[idx].detach().numpy()}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "4934c513",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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LlyY7du306hRI3NAnDp1KtHR0dSqVSvF+xfJaRSiRET+I2zdOoJHjSbu6lVzm13BgkzKl5dixYrh5ubGqFGjUjSRKkDBggUJCAhg9uzZbNmyhd27dxMeHk65cuWAe5f6DMOgQYMG5m18fHwoXbq0xd1+devWNf/Z3d2dMmXKcOrUqVR9t/fff9/8Z09PTwBiY2MBKFeuHKtWreLSpUuEh4dz/PhxXcoTeQRdzhMR+Z+wdeu41Ku3RYACCLl0ie+WLKFHQAAff/wxP/74I2fOnEnRPvft20eFChXYuXMnr776Khs3bqRdu3bm5ffHRj04nsrGxsZi3NSDd3Pa2toSHx+fqu9XokSJZJf5+/sTHByMj48P5cqV4/XXX6dFixap2r9ITqMQJSLCvUt4waNGQxJPwpp78yZONja8uG8fr7RsSZEiRQgMDEzRfhcsWICnpye///47PXr0oGrVqhY9SNWqVcNkMrFx40Zz26VLlzh+/DjVq1c3t/3111/mP0dERHDixAlKliyZqu9oa2ub7LIePXqwaNEizp49y7Vr1xI9m1FEElOIEhGBe2OgHuiBAgiLj+en27d40yMPttdCiN5/gN69ezN37lwuXbr0yP3mz5+f4OBgFi1axKpVq3jppZfYvn07cXFxAPj5+fHuu+/St29fZs2axapVq2jRogXe3t507NjRvJ9NmzYxaNAgc09WQkKCxfLH5eLiwqxZszh58iQXLlzg9OnTqe7pEslpFKJERIC4ZO50+/7WLWINgzc9PMzrderUCRcXF7766qtH7rd37960atWKzp07061bN4oWLUr37t3ZuXOnOUjNmDGD7t27M3jwYFq3bo2Pjw+bN2+2mOn+gw8+YOvWrTRt2pQLFy6wdu1avL29H/+L/0/btm3ZuHEjr7/+OtWqVaNUqVIULFjQogdMRCyZDCOJvussKqs+BVpEMt6dnbs43779I9crOm8eLjVrpENF6efUqVNUrFiR7777jhIlSmAymbh06RIff/wxrVq1Yvz48RldomRzWfX3W3fniYgAztWqYlewIHHBwUmOi8Jkwq5AAZyrZb/n0hUvXpxevXoxfPhwLl++TFxcHIUKFaJRo0apmkJBJKdRT5SIyP/cvzsPsAxS/7tzrvCkibg1apT+hYlkc1n191tjokRE/setUSMKT5qIXYECFu12BQooQIlIIrqcJyLyH26NGuFav36iGctND5keQERyJoUoEZEHmGxts93gcRF58nQ5T0RERMQKClEiIiIiVlCIEhH5n7lz52Iymfj222/NbUFBQZhMJubOnWuxXrFixdK/QBHJVBSiREQeMG3atIcub9asGStWrEinakQks1KIEhF5wN69e9m9e3eyy/Ply0elSpXSsSIRyYwUokREHuDt7f3I3igREYUoEZEHdOnShYULF3L79u0klyc3JqpDhw506NDBom348OG88MILAJw9exaTyZTo9eA248ePx9fXF0dHR+rXr8+RI0cSfcaKFSsoV64cLi4uNGnShOvXr5vXOX/+PAEBAbi6ulKzZk3GjBmDn58fn3/+uTWHQ0SSoRAlIvKADh06YDKZmDdv3hPdr7e3N7t37za/7vd21atXz7zOyJEjGThwIO+99x7Lly/HxsaGOnXqcP78efM6e/bsoUePHgwePJg5c+awbds2AgMDzcs7deqEyWRi5cqVlC1bllGjRvHTTz/Rpk2bJ/p9RHI6TbYpIjlaQkI8l479TcTtW9y8dAEADw8P2rZty/Tp05/oZb1cuXJRrVo1AEJCQnjllVfo1q0b7du3ByAyMpLAwED69u1L//79AahduzYlSpRgwoQJTJgwAYCjR4+ya9cu8742b97MwYMHzZ+zfft2Fi9eTN26dfHy8mL+/PkULVqUQoUKPbHvIiIKUSKSg53auY0/5s4k4ua9S2G7z9wLUf/s2cl7773H7Nmz2bRp02N9RkJCQqK2uLg43njjDXx8fJg8ebK5/e+//yYyMpIGDRqY23Lnzk3NmjUtBrrXqlXLHKAAPD09+fvvv83vy5Urx+rVq6lbty4rV64kX758FHjgeYAi8vh0OU9EcqRTO7exfPwoc4D6r9VTx+MSHUnt2rWZPXv2Y33OhQsXErX179+fY8eO8csvv5ArVy5zu2EYAJhMJov1bWxszMsASpQo8dDP9Pf359tvv8XFxYUvvviCuXPnYmOjv+5FnjT9v0pEcpyEhHj+mDvzoetsmjeT7t27c/ny5RTv187OjsjISPP7O3fusHr1aot1fvrpJ6ZMmcLixYvx9va2WFahQgWcnZ3ZuHGjxT527NhB9erVzW22D3kY8r59+1i2bBk3btzgxIkTXL16laZNm6b4O4hIyulynojkOJeO/Z1kD9R/hd+4Tv1K5fHy8uLatWsp2m+VKlUYPnw4//77L3ny5KFTp04WPUhHjx6lc+fOdOjQAUdHR/bs2WNeVq1aNVxcXBgwYABffPEF7u7uVKlShbFjxxITE0OfPn1SVIOLiws3b95k2rRp1KhRg7t371KoUCG8vLxStL2IpJxClIjkOBG3b6VovZg7EXTu3JlRo0alaP0uXbqwbds2/P39cXd3p1u3blSqVInNmzcDsGvXLiIjI5k1axazZs2y2PZ+2BoyZAjOzs5MmjSJa9euUbt2bbZs2ULRokVTVEOJEiWoVq0ao0aNIiIigqioKODeHYC///47Tk5OKdqPiDyayfjvP5OyuLCwMNzd3QkNDcXNzS2jyxGRTOrC34dY9NmgR673+tBRFKlQOR0qenKGDBnCunXrGDVqFK6ursTGxrJlyxYGDRrEwYMHqVw5a30fyRmy6u+3eqJEJMcpXK4CufPmf+glPdd8+SlcrkI6VvVkvP322xw4cIC2bdty69YtHBwcKFu2LJMnT1aAEnnCFKJEJMexsbHlxQ5dWT4++ct09dp3xcYm+QHcmVWZMmX0cGSRdKK780QkRypVszbN+wwid978Fu2u+fLTvM8gStWsnUGViUhWoZ4oEcmxStWsTYnqNc0zluf2yEPhchWyZA+UiKQ/hSgRydFsbGyz3OBxEckcdDlPRERExAoKUSIiIiJWUIgSERERsYJClIiIiIgVFKJERERErKAQJSIiImIFhSgRERERKyhEiYiIiFghU4aoI0eOUL16dfLkyUO/fv0wDCOjSxIRERGxkOlCVHR0NM2aNaNq1ars2bOHo0ePMnfu3IwuS0RERMRCpgtRq1evJjQ0lPHjx1OiRAlGjRrFt99+m9FliYiIiFjIdM/OO3jwILVq1cLZ2RmAypUrc/To0STXjY6OJjo62vw+LCwsXWoUERERyXQ9UWFhYRQvXtz83mQyYWtry61btxKtO3r0aNzd3c2vIkWKpGepIiIikoNluhBlZ2eHg4ODRZujoyORkZGJ1h04cCChoaHm14ULF9KrTBEREcnhMt3lvLx583LkyBGLtvDwcHLlypVoXQcHh0SBS0RERCQ9ZLqeqOrVq7Njxw7z+7NnzxIdHU3evHkzsCoRERERS5kuRNWpU4fQ0FDmz58PQGBgIA0aNMDW1jaDKxMRERH5f5nucp6dnR0zZ86kbdu29OvXj/j4eDZv3pzRZYmIiIhYyHQhCqBly5acOnWKPXv2ULt2bTw9PTO6JBERERELmTJEARQuXJjChQtndBkiIiIiScp0Y6JEREREsgKFKBERERErKESJiIiIWEEhSkRERMQKClEiIiIiVlCIEhEREbGCQpSIiIiIFRSiRERERKygECUiIiJiBYUoERERESsoRImIiIhYQSFKRERExAoKUSIiIiJWUIgSERERsYJClIiIiIgVFKJERERErKAQJSIiImIFhSgRERERK6QqRG3cuJEvv/ySX3/9ldjYWItlMTExdOzY8YkWJyIiIpJZpThEjRgxgmbNmrF69Wp69epFyZIl+fXXX83LY2NjmTdvXpoUKSIiIpLZpDhETZo0iVWrVhEUFMT58+cZOnQoXbt2pXPnzsTExKRljSIiIiKZTopDVHR0NH5+fvc2srGhU6dOHD58mH/++YdatWpx5syZNCtSREREJLNJcYh6+eWXef/99wkPDze3eXt7s3HjRurVq8dzzz2XJgWKiIiIZEYpDlFz5syhYMGCfPDBB5Y7sLFh3LhxTJw4kcqVKz/xAkVEREQyI5NhGEZqNjAMA5PJlFb1PJawsDDc3d0JDQ3Fzc0to8sRERGRFMiqv9+pnicqswYoERERkfSkyTZFRERErKAQJSIiImIFhSgRERERKyhEiYiIiFhBIUpERETECgpRIiIiIlZIcYj673RSd+7cSXa93r1761l6IiIiku2lOETlzZsXuPcMvZo1aya5zq1bt5g2bRq2trZPpjoRERGRTCrFIcrFxYWEhARMJhP29vYAxMbGMnDgQG7fvg3AlStXKFu2rEKUiIiIZHspDlH29vZMnz4dR0dHDh06hK2tLb169WLJkiVUrVqVvXv3sn//fp555pm0rFdEREQkU0hxiDKZTHTp0oWIiAgqVarEkSNHMAwDZ2dnfvrpJ9544w2mTJnCSy+9lJb1ioiIiGQKjwxR586do2fPnoSGhmJvb4+zszM2NjY4ODiY16lRowa9evViz549NGrUKE0LFhEREckMHhmizp49y+XLl8mVKxcJCQkWd+ndt379eiZMmECtWrXYsmVLmhQqIiIikpk8MkTVrVuXpUuX4ujoyMKFC7G1teXgwYOUKlUKgIiICD799FNWr17N4MGD+fnnn9O8aBEREZGMlqrJNl9//XXCwsKoUKECERERjBs3DoBt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ylQUorI5p4r5yfd2OWzdLS/Z2bo7kO/tcjhVzJ9BlYmISGZmMtlSutTQ++8eXApA6VJDMJly7mTHmmwzB3CqmB/H8vlSPGO5iIgIgJdXAJUqTuXkqc8spjlwcChI6VJD8PIKyMDqMp5CVA5hsjHhWMIjo8sQEZEsxssrAE/PBhYzlnt4VM/RPVD3KUSJiIjIQ5lMto89eDw70pgoERERESsoRImIiIhYQSFKRERExAoKUSIiIiJWUIgSERERsYJClIiIiIgVFKJERERErKAQJSIiImIFhSgRERERKyhEiYiIiFhBIUpERETECgpRIiIiIlZQiBIRERGxgkKUiIiIiBUUokRERESsoBAlIiIiYgWFKBERERErKESJiIiIWEEhSkRERMQKClEiIiIiVlCIEhEREbGCQpSIiIiIFRSiRERERKygECUiIiJiBYUoERERESsoRImIiIhYQSFKRERExAoKUSIiIiJWUIgSERERsYJClIiIiIgVFKJERERErKAQJSIiImIFhSgRERERKyhEiYiIiFhBIUpERETECgpRIiIiIlZQiBIRERGxgkKUiIiIiBUUokRERESsoBAlIiIiYgWFKBERERErKESJiIiIWEEhSkRERMQKClEiIiIiVlCIEhEREbFCpgpRy5Ytw8/PDzs7O2rWrMmxY8cyuiQRERGRJGWaEPXPP//w7rvvEhgYyKVLl/D19aVz584ZXZaIiIhIkuwyuoD7jh07xqhRo3j99dcB6NGjB40bN87gqkRERESSlmlCVNOmTS3enzhxgpIlSz50m+joaKKjo83vw8LC0qQ2ERERkQel++W8li1b4uHhkeg1ZcoU8zoxMTGMHTuWnj17PnRfo0ePxt3d3fwqUqRIWpcvIiIiAoDJMAwjPT8wODiYu3fvJmrPmzcvbm5uAPTv359169axe/du7O3tk91XUj1RRYoUITQ01LwvERERydzCwsJwd3fPcr/f6X45r0CBAg9dvn79eqZPn86OHTseGqAAHBwccHBweJLliYiIiKRIprk7D+Dff//lrbfeYtq0aZQvXz6jyxERERFJVqYZWH737l2aNm1Ky5YtadGiBREREQC4uLhgMpkyuDoRERERS5mmJ2rt2rUcO3aMWbNm4erqan6dO3cuo0sTERERSSTT9ES1bNmSdB7jLiIiImK1TNMTJSIiIpKVKESJiIiIWEEhSkRERMQKClEiIiIiVlCIEhEREbGCQpSIiIiIFRSiRERERKygECUiIiJiBYUoERERESsoRImIiIhYQSFKRERExAoKUSIiIiJWUIgSERERsYJClIiIiIgVFKJERERErKAQJSIiImIFhSgRERERKyhEiYiIiFhBIUpERETECgpRIiIiIlZQiBIRERGxgkKUiIiIiBUUokRERESsoBAlIiIiYgWFKBERERErKESJiIiIWEEhSkRERMQKClEiIiIiVlCIEhEREbGCQpSIiIiIFRSiRERERKygECUiIiJiBYUoERERESsoRImIiIhYQSFKRERExAoKUSIiIiJWUIgSERERsYJClIiIiIgVFKJERERErKAQJSIiImIFhSgRERERKyhEiYiIiFhBIUpERETECgpRIiIiIlZQiBIRERGxgkKUiIiIiBUUokRERESsoBAlIiIiYgWFKBERERErKESJpIGgoCBMJpP55eHhQcOGDfn7778zujQREXlCFKJE0tAPP/zA7t27WbJkCYZh0LhxYyIiIjK6LBEReQLsMroAkeysfPny+Pv7A+Dj40Pp0qXZunUrjRs3ztjCRETksaknSiSd2Njc+79bVFRUBlciIiJPgkKUSDq4efMmw4YNw93dneeffx6AtWvX4u/vj4ODAxUqVGDJkiUW2xw6dIj69evj5uaGp6cnHTt25M6dO+bl0dHR9OrVC29vb1xcXHjmmWfYtWtXun4vEZGcTCFKJA099dRTmEwm8uXLxy+//MJvv/1Gvnz5CAoK4uWXX6ZatWqsWrWKBg0a8Oqrr7JixQrzti1atCA2NpZly5YxdepU1q5dy8iRI83LR48ezbfffsvYsWNZtmwZhQsXpkWLFhiGkRFfVUQkx9GYKJEnJD4hnn3X9hESGcL5m+cBWLhwIWXKlOHixYuMGjWKt956i7/++ovhw4dTq1YtZs+eDUD9+vU5ffo0Q4cOpVmzZsTFxXHx4kW6d+9OvXr1AChVqhRxcXHmzzt79ixFixblzTffxGQyUaVKFXbu3ElcXBz29vbpfwBERHIYhSiRJ2DDuQ0E7gokODIYgIhj9+7Au+V6C39/f/z9/alduzaenp58+eWX7N69m759+1rso379+vTt25fY2Fjs7e3p3r07Q4YMYfPmzVSvXp2XXnqJmjVrmtfv2LEjixcvpnLlytStW5dnn32W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b3HhwgWWLVvGzp07adKkySM/KywsjEOHDlG1alUA7OzsWLBgAU2aNOGjjz5i0qRJLFq0iHz58lnztUVEFKJEJPXu3r370OURERGcPn2aEydO4OzsbG63t7dn6dKlFChQwDwhZsuWLenevTuNGzdOct9Dhw5lzJgx5MuXj2rVqlG5cmXs7e3Nl/Pi4uK4efMm/v7+REZG4urqyt69e/nuu+94/vnnyZ07t3m/Z86coXDhwnz00UdUq1bNXF+hQoXIkydPsncMiogkRY99EZFU+/7771m4cGGycz3FxsZStmxZcufOzVdffUVAQADBwcEEBATg5uZmMebpn3/+wdPTEzc3N3NbVFQU/v7+TJ8+nfPnzxMZGUnZsmXNy//66y8+/vhjduzYkWyNX331FRUrViQyMpKhQ4cSHx9P7dq1eeONN6hTpw7r1q1j1apV7Nixg2PHjtGjRw8mT578BI6OiOQUClEikq3FxMQQERFB3rx5k10nNjaW+Pj4FE24KSJyn0KUiIiIiBVSNsOciIiIiFhQiBIRERGxgkKUiIiIiBUUokRERESsoBAlIiIiYgWFKBERERErKESJiIiIWEEhSkRERMQK/wc3DQ/U5hsmGwAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 绘制二维词向量图\n",
    "plt.rcParams[\"font.family\"]=['SimHei'] # 用来设定字体样式\n",
    "plt.rcParams['font.sans-serif']=['SimHei'] # 用来设定无衬线字体样式\n",
    "plt.rcParams['axes.unicode_minus']=False # 用来正常显示负号\n",
    "fig, ax = plt.subplots() \n",
    "for word, idx in word_to_idx.items():\n",
    "    # 获取每个单词的嵌入向量\n",
    "    vec = skipgram_model.input_to_hidden.weight[idx].detach().numpy() \n",
    "    ax.scatter(vec[0], vec[1]) # 在图中绘制嵌入向量的点\n",
    "    ax.annotate(word, (vec[0], vec[1]), fontsize=12) # 点旁添加单词标签\n",
    "plt.title(' 二维词嵌入 ') # 图题\n",
    "plt.xlabel(' 向量维度 1') # X 轴 Label\n",
    "plt.ylabel(' 向量维度 2') # Y 轴 Label\n",
    "plt.show() # 显示图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3520ac90",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
